#include <bits/stdc++.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

using namespace std;

string testFile = "/data/test_data.txt";
string resultFile = "/projects/student/result.txt";

int node_num = 0;
uint nodes[2*280000];
unordered_map<uint, int> idHash;
int G[280000][50];
int len[280000];
int ans3[500000][3], p3=0;
int ans4[500000][4], p4=0;
int ans5[1000000][5], p5=0;
int ans6[2000000][6], p6=0;
int ans7[3000000][7], p7=0;

inline unsigned int parse(char** s){
	char *p = *s;
	unsigned int val = *(p++) - '0';
	while(*p != ','){
		val = 10*val + *(p++) - '0';
	}
	*s = p+1;
	return val;
}

void loadData_and_createGrap(){
	int fd = open(testFile.c_str(), O_RDONLY);
    int file_size = lseek(fd, 0, SEEK_END);
    char* p_map =(char*)mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
    close(fd);
	char *p = p_map;
	uint inputs[2*280000], n=0;
	while(*p != '\0'){
		inputs[n++]=(parse(&p));
		inputs[n++]=(parse(&p));
		while(*p != '\n') p++;
		p++;
	}
	memcpy(nodes,inputs,4*2*280000);
	sort(nodes,nodes+2*280000);//排序
	node_num = unique(nodes,nodes+2*280000) - nodes;//去重
	for(int i=0; i<node_num; i++){idHash[nodes[i]] = i;len[i]=0;}
	for(int i=0,a=0; i<n; i+=2){a=idHash[inputs[i]];G[a][len[a]++]=idHash[inputs[i+1]];}
	for(int i=0; i<node_num; i++) sort(G[i],G[i]+len[i]);
	munmap(p_map, file_size);
}

char buf[77*3*1000000];
void save(){

	int data_size = sprintf(buf,"%d\n",p3+p4+p5+p6+p7);
	int i=0;
	for(i=0; i<p3; i++) data_size += sprintf(buf+data_size,"%u,%u,%u\n",nodes[ans3[i][0]],nodes[ans3[i][1]],nodes[ans3[i][2]]);
	for(i=0; i<p4; i++) data_size += sprintf(buf+data_size,"%u,%u,%u,%u\n",nodes[ans4[i][0]],nodes[ans4[i][1]],nodes[ans4[i][2]],nodes[ans4[i][3]]);
	for(i=0; i<p5; i++) data_size += sprintf(buf+data_size,"%u,%u,%u,%u,%u\n",nodes[ans5[i][0]],nodes[ans5[i][1]],nodes[ans5[i][2]],nodes[ans5[i][3]],nodes[ans5[i][4]]);
	for(i=0; i<p6; i++) data_size += sprintf(buf+data_size,"%u,%u,%u,%u,%u,%u\n",nodes[ans6[i][0]],nodes[ans6[i][1]],nodes[ans6[i][2]],nodes[ans6[i][3]],nodes[ans6[i][4]],nodes[ans6[i][5]]);
	for(i=0; i<p7; i++)data_size += sprintf(buf+data_size,"%u,%u,%u,%u,%u,%u,%u\n",nodes[ans7[i][0]],nodes[ans7[i][1]],nodes[ans7[i][2]],nodes[ans7[i][3]],nodes[ans7[i][4]],nodes[ans7[i][5]],nodes[ans7[i][6]]);
	int fd = open(resultFile.c_str(), O_RDWR|O_CREAT, 0666);
	write(fd, buf, data_size);
	close(fd);
}

int main(int argc, char* argv[]){
	loadData_and_createGrap();
	vector<unordered_map<int,vector<int>>> P1(node_num);
	unordered_map<int,vector<int>>::iterator iter;
	vector<int> uSet2, uSet3, uSet4;
	int p[7];
	for(int u=0; u<node_num; u++){
		for(int i=0,v1=G[u][0]; i<len[u]; v1=G[u][++i]){
			for(int j=0,v2=G[v1][0]; j<len[v1]; v2=G[v1][++j]){
				if(v2>v1 || v2==u) continue;
				P1[u][v2].push_back(v1);
			}
		}
	}
	for(int u=0; u<node_num; u++){
		p[0]=u;
		for(int i=0,v1=G[u][0]; i<len[u]; v1=G[u][++i]){
			if(v1 < u) continue;
			p[1]=v1;
			for(int j=0,v2=G[v1][0]; j<len[v1]; v2=G[v1][++j]) if(v2 > u) uSet2.push_back(v2);
			for(int& v2:uSet2){
				p[2]=v2;
				if(find(G[v2],G[v2]+len[v2],u)!=G[v2]+len[v2]){
					memcpy(ans3+p3++,p,12);
				}
				for(int k=0,v3=G[v2][0]; k<len[v2]; v3=G[v2][++k]) if(v3 > u && v3!=v1) uSet3.push_back(v3);
				for(int& v3:uSet3){
					p[3]=v3;
					if(find(G[v3],G[v3]+len[v3],u)!=G[v3]+len[v3]){
						memcpy(ans4+p4++,p,16);
					}
					for(int m=0,v4=G[v3][0]; m<len[v3]; v4=G[v3][++m]) if(v4 > u && v4!=v2 && v4!=v1) uSet4.push_back(v4);
					for(int& v4:uSet4){
						p[4]=v4;
						if(find(G[v4],G[v4]+len[v4],u)!=G[v4]+len[v4]){
							memcpy(ans5+p5++,p,20);
						}
					}
					uSet4.clear();
				}
				uSet3.clear();
			}
			uSet2.clear();
		}
	}
	for(int u=0; u<node_num; u++){
		p[0]=u;
		for(int i=0,v1=G[u][0]; i<len[u]; v1=G[u][++i]){
			if(v1 < u) continue;
			p[1]=v1;
			for(int j=0,v2=G[v1][0]; j<len[v1]; v2=G[v1][++j]){
				if(v2 <= u) continue;
				p[2]=v2;
				for(int k=0,v3=G[v2][0]; k<len[v2]; v3=G[v2][++k]){
					if(v3 <= u || v3==v1) continue;
					p[3]=v3;
					for(int m=0,v4=G[v3][0]; m<len[v3]; v4=G[v3][++m]){
						if(v4 <= u || v4==v2 || v4==v1) continue;
						p[4]=v4;
						if((iter = P1[v4].find(u))!=P1[v4].end()){
							for(int& v5:iter->second){
								p[5] = v5;
								if(v5!=v3 && v5!=v2 && v5!=v1){
									memcpy(ans6+p6++,p,24);
								}
							}
						}
					}
				}
			}
		}
	}
	for(int u=0; u<node_num; u++){
		p[0]=u;
		for(int i=0,v1=G[u][0]; i<len[u]; v1=G[u][++i]){
			if(v1 < u) continue;
			p[1]=v1;
			for(int j=0,v2=G[v1][0]; j<len[v1]; v2=G[v1][++j]){
				if(v2 <= u) continue;
				p[2]=v2;
				for(int k=0,v3=G[v2][0]; k<len[v2]; v3=G[v2][++k]){
					if(v3 <= u || v3==v1) continue;
					p[3]=v3;
					for(int m=0,v4=G[v3][0]; m<len[v3]; v4=G[v3][++m]){
						if(v4 <= u || v4==v2 || v4==v1) continue;
						p[4]=v4;
						for(int n=0,v5=G[v4][0]; n<len[v4]; v5=G[v4][++n]){
							if(v5 <= u || v5==v3 || v5==v2 || v5==v1) continue;
							p[5]=v5;
							if((iter = P1[v5].find(u))!=P1[v5].end()){
								for(int& v6:iter->second){
									p[6] = v6;
									if(v6!=v4 && v6!=v3 && v6!=v2 && v6!=v1){
										memcpy(ans7+p7++,p,28);
									}
								}
							}
						}
					}
				}
			}
		}
	}
	save();
	exit(0);
}